import {isObject} from "../base/base";
import errorCodes from './errors';

//获取返回结果字符串
var parseResponseText = async response => {
    var text = response.text;
    if(text instanceof Promise){
        text = await text;
    }
    return text;
}

//判断请求是否为 cess 格式数据
function _iscess(response,config){
    if(response.headers['__cess_media_type__']){
        return true;
    }

    //如果指定为 cess 格式请求，则在请求中加入 application/cess2+json 或 application/cess+json
    //addHeader("Accept", "application/cess2+json");
    var header = config.headers['Accept'] || config.headers['accept'] || '';
    if(header.indexOf('cess') != -1){
        return true;
    }

    return false;
}

async function _httpErrorProcess(response,isCess){
    //如果是 cess 格式数据
    if(isCess){
        var error = undefined;

        let responseText = undefined;
        try{
            let responseText = await parseResponseText(response);
            error = responseText && JSON.parse(responseText);
            if(!isObject(error)){
            	//如果不是对象
            	error = {
            	    code: errorCodes.WHITOUT_ERROR_CODE,
            		message: 'http 错误',
            		stackTrace: responseText,
            	}
            }
            //如果无错误码，则把错误码设置为603
            error.code = error.code || errorCodes.WHITOUT_ERROR_CODE;
        }catch(e){

        }
        //如果返回结果不能转为 JSON 格式数据
        if(!error) {
            error = {
                message: 'http错误',
                stackTrace: responseText,
            };
            if(response.status != 0){
                error.code = errorCodes.CLIENT_ERROR;
            }else{
                //response.status 表示发生的网络错误
                error.code = errorCodes.NETWOK_ERROR_CODE;
            }
        }
        error.code = error.code || response.status;
        //http 请求状态码
        error.$status = response.status;
        throw error;
    }else{
        throw response;
    }
}

function _cess1DataProcess(response,data){

	data = data || {};

    if (data.code === undefined || data.code === null || data.code != 0) {
        //如果 data.code 非0表示发生错误
    	//http 请求状态码
        data.$status = response.status;
        //如果是 cess 1.0 版本，则用 r.code 不为 0，表示返回的错误信息
        throw data;
    }


    //对返回结果进行处理，把基本类型转化为对象类型
    //其目的是为了能够携带警告信息，为了保持返回结果的一致性，不管有没有警告信息都对结果进行处理
    if(!data.result){
        //如果无返回数据
        //设为空对象
        data.result = {};
    }else if(typeof data.result == 'number'){
        //如果为数字
        data.result = new Number(data.result);
    }else if(typeof data.result == 'string'){
        //如果为字符串
        data.result = new String(data.result);
    }

    //如果有警告信息
    if(data.warnings){

        try{
            //把警告信息写到返回结果的 $warnings 属性中
            data.result.$warnings = data.warnings;
        }catch(e){
            //防止特殊情况下，添加 $warnings 属性失败
            //如果失败，只把出错误信息，代码继续执行
            console.error(e);
        }
    }

    return data.result;

}

function _cess2DataProcess(response, data){

    data = data || {};

    //__http_comm_with_error__ 请求表示是否返回的错误信息
    //如果有 __http_comm_with_error__ 响应头，则表示返回的是错误信息
    if('__http_comm_with_error__' in response.headers){
    	//http 请求状态码
        data.$status = response.status;
        throw data;//抛出错误信息
    }else if('__http_comm_with_warning__' in response.headers){
        //如果有 __http_comm_with_error__ 响应头，则表示返回的数据中有警告信息
        //此时数据则是 cess 1.0 的格式
        return _cess1DataProcess(response, data);
    }
    //如果没有错误信息，则直接返回数据
    return data;

}

//默认响应数据处理方法
export default async function defaultResponseHandler(response,config){

    //判断是否为 cess 格式数据
    var isCess = _iscess(response,config);
    //进行错误处理
    if(response.status != 200){
        return await _httpErrorProcess(response,isCess);
    }

    //如果不是 cess 格式数据，并且也不是 json 格式数据
    if(!isCess && (response.headers['content-type'] || '').indexOf('json') == -1){
        //直接返回
        return response;
    }

    var mediaType = response.headers['__cess_media_type__'];

    //返回的结果数据
    var resutlData = undefined;
    try {
        //解析返回结果
        let responseText = await parseResponseText(response);
        resutlData = JSON.parse(responseText);
    } catch (e) {
        if(mediaType){//如果是 cess 格式的数据
            throw { code: 4, message: 'json解析错误' };
        }else{
            throw e;
        }
    }

    if(!mediaType){
        //如果没有 cess 格式数据说明，直接返回
        return resutlData;
    }

    //__cess_media_type__ 用于表示返回的数据类型
    //cess 2.0 返回 application/cess2+json
    if(mediaType.indexOf('cess2') != -1){
        //如果是 cess 2.0 的格式
        return _cess2DataProcess(response,resutlData)
    }

    return _cess1DataProcess(response,resutlData)

}
